#include "spinlock.h"
#include "kernel.h"
#include "atomic.h"
#include "intr.h"

void os_spin_init(struct spinlock *lock, char *name)
{
    lock->locked = 0;
    lock->name = name;
}

int os_spin_lock(struct spinlock *lock, u32 *pflags)
{
    u32 flags;

    if (!lock || !pflags) {
        return -1;
    }

    // 记录 cpu 当前中断状态
    flags = os_cpu_intr_get();
    *pflags = flags;

    // 关闭中断
    os_cpu_intr_dis();

    // 尝试获取锁
    while(xchg((u32 *)&lock->locked, 1) != 0);

    // 内存屏障
    smp_mb();

    return 0;
}

int os_spin_unlock(struct spinlock *lock, u32 flags)
{
    if (!lock) {
        return -1;
    }

    // 释放锁
    xchg((u32 *)&lock->locked, 0);

    // 内存屏障
    smp_mb();

    // 恢复之前中断状态
    os_cpu_intr_put(flags);

    return 0;
}